package io.github.talelin.latticy.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.github.talelin.autoconfigure.exception.NotFoundException;
import io.github.talelin.latticy.model.AreaDO;
import io.github.talelin.latticy.mapper.AreaMapper;
import io.github.talelin.latticy.service.AreaService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.github.talelin.latticy.util.JedisUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author generator@wulongbo
 * @since 2022-05-11
 */
@Service
public class AreaServiceImpl extends ServiceImpl<AreaMapper, AreaDO> implements AreaService {

    @Override
    public List<AreaDO> getCJERegion() {
        String region = JedisUtils.get("region");
        return Optional.ofNullable(region).map(r -> JSONObject.parseArray(r, AreaDO.class)).orElseGet(
                () -> {
                    QueryWrapper<AreaDO> wrapper = new QueryWrapper<>();
                    wrapper.lambda().eq(AreaDO::getParentId, 0);
                    List<AreaDO> list = baseMapper.selectList(wrapper);
                    Optional.ofNullable(list).orElseThrow(() -> new NotFoundException(18302));
                    String jsonString = JSONObject.toJSONString(list);
                    JedisUtils.set("region", jsonString, 0);
                    return list;
                }
        );
    }

    @Override
    public List<AreaDO> getAllArea(Integer id) {
        boolean flag = JedisUtils.hExists("area", String.valueOf(id));
        List<AreaDO> areaDOList = null;
        if (flag) {
            String area = JedisUtils.hget("area", String.valueOf(id));
            areaDOList = JSONObject.parseArray(area, AreaDO.class);
            return areaDOList;
        }
        QueryWrapper<AreaDO> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(AreaDO::getParentId, id);
        areaDOList = this.baseMapper.selectList(wrapper);
        Optional.ofNullable(areaDOList).orElseThrow(() -> new NotFoundException(18302));
        String jsonString = JSONObject.toJSONString(areaDOList);
        JedisUtils.hset("area", String.valueOf(id), jsonString);
        return areaDOList;
    }

    @Override
    public List<AreaDO> getProvinces(Integer id) {
        boolean flag = JedisUtils.hExists("province", String.valueOf(id));
        List<AreaDO> areaDOList = null;
        if (flag) {
            String province = JedisUtils.hget("province", String.valueOf(id));
            areaDOList = JSONObject.parseArray(province, AreaDO.class);
            return areaDOList;
        }
        QueryWrapper<AreaDO> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(AreaDO::getParentId, id);
        areaDOList = this.baseMapper.selectList(wrapper);
        Optional.ofNullable(areaDOList).orElseThrow(() -> new NotFoundException(18302));
        String jsonString = JSONObject.toJSONString(areaDOList);
        JedisUtils.hset("province", String.valueOf(id), jsonString);
        return areaDOList;
    }

    @Override
    public List<AreaDO> getCitys(Integer id) {
        boolean flag = JedisUtils.hExists("city", String.valueOf(id));
        List<AreaDO> areaDOList = null;
        if (flag) {
            String city = JedisUtils.hget("city", String.valueOf(id));
            areaDOList = JSONObject.parseArray(city, AreaDO.class);
            return areaDOList;
        }
        QueryWrapper<AreaDO> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(AreaDO::getParentId, id);
        areaDOList = this.baseMapper.selectList(wrapper);
        Optional.ofNullable(areaDOList).orElseThrow(() -> new NotFoundException(18302));
        String jsonString = JSONObject.toJSONString(areaDOList);
        JedisUtils.hset("city", String.valueOf(id), jsonString);
        return areaDOList;
    }

    @Override
    public boolean checkAreaExistByAreaId(Integer areaId) {
        boolean flag = JedisUtils.hExists("area", String.valueOf(areaId));
        if (flag) {
            return true;
        }
        checkExistByDB(areaId);
        return true;
    }

    @Override
    public boolean checkAreaExistByProvinceId(Integer provinceId) {
        boolean flag = JedisUtils.hExists("province", String.valueOf(provinceId));
        if (flag) {
            return true;
        }
        checkExistByDB(provinceId);
        return true;
    }

    @Override
    public boolean checkAreaExistByCityIdId(Integer cityId) {
        boolean flag = JedisUtils.hExists("city", String.valueOf(cityId));
        if (flag) {
            return true;
        }
        checkExistByDB(cityId);
        return true;
    }

    private void checkExistByDB(Integer id) {
        QueryWrapper<AreaDO> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(AreaDO::getId, id);
        AreaDO areaDO = this.baseMapper.selectOne(wrapper);
        Optional.ofNullable(areaDO).orElseThrow(()->new NotFoundException(18302));
    }

}
